﻿using System;


using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace DKE_Kinect.Entwicklung.Grafik
{
	/// <summary>
	/// Repräsentiert einen Übergang des Farb-Alpha - Wertes von 0 bis 255, um eine Textur einzublenden oder eine Textur zur anderen zu faden.
	/// </summary>
	public class TextureAlphaFadeTransition : TransitionEffect<float>
	{
		private float pMerged;

		/// <summary>
		/// Instanziiert ein neues Objekt dieser Klasse.
		/// </summary>
		/// <param name="Duration">Dauer des Verlaufes.</param>
		/// <param name="StartAlpha">Startender Alphawert zwischen 0 und 1.</param>
		/// <param name="EndAlpha">Endender Alphawert zwischen 0 und 1.</param>
		public TextureAlphaFadeTransition (float StartAlpha, float EndAlpha, long Duration)
			: base(StartAlpha, EndAlpha, Duration)
		{
			if ((StartAlpha < 0f) || (StartAlpha > 1f) || (EndAlpha < 0f) || (EndAlpha > 1f))
				throw new ArgumentOutOfRangeException();

			this.pMerged = StartAlpha;
		}

		/// <summary>
		/// Der Alphawert in Prozenten zwischen 0 und 1.
		/// </summary>
		public override float Merged { get { return this.pMerged; } }

		/// <summary>
		/// Setzt den Alphawert auf einen Basiswert zurück.
		/// </summary>
		/// <param name="Orig"></param>
		protected override void ResetMerged (float Orig)
		{
			this.pMerged = Orig;
		}

		/// <summary>
		/// Aktualisiert den prozentualen Alphawert.
		/// </summary>
		protected override void UpdateValues (TransitionInterpolation InPol)
		{
			switch (InPol)
			{
				case TransitionInterpolation.Linear:
					this.pMerged = MathHelper.Lerp(base.pOrig, base.pDest, this.Percent);
					break;

				case TransitionInterpolation.Quadratic:
					this.pMerged = (base.pOrig < base.pDest) ? this.Percent * this.Percent : 1 - this.Percent * this.Percent;
					break;

				case TransitionInterpolation.Cubic:
					this.pMerged = MathHelper.SmoothStep(base.pOrig, base.pDest, this.Percent);
					break;

				case TransitionInterpolation.SquareRoot:
					this.pMerged = (base.pOrig < base.pDest) ? (float)Math.Sqrt(this.Percent) : 1f - (float)Math.Sqrt(this.Percent);
					break;

				default:
					break;
			}
		}

		/// <summary>
		/// Zeichnet zwei Texturen auf ein Sprite, wobei die Zieltextur mit dem derzeitigen Alphawert auf die andere überzeichnet wird.
		/// </summary>
		/// <param name="Sprite">Das Sprite, auf dem gezeichnet wird.</param>
		/// <param name="OriginalTexture">Die Originaltextur.</param>
		/// <param name="DestinationTexture">Die Zieltextur, die Anfangs transparant wird, mit der entsprechendem Alphawert aber undurchsichtig.</param>
		/// <param name="color">The color.</param>
		/// <param name="Pos">An welcher Stelle gezeichnet werden soll.</param>
		/// <param name="Src">Quellrechteck.</param>
		/// <param name="Origin">Vektor, der den Nullpunkt der Texturen darstellt.</param>
		/// <param name="Scale">Skalierungsfaktor</param>
		public void Draw (SpriteBatch Sprite, Texture2D OriginalTexture, Texture2D DestinationTexture, Color color, Vector2 Pos, Rectangle? Src, Vector2 Origin, Vector2 Scale)
		{
			if (this.pMerged.Equals(0f))
				Sprite.Draw(OriginalTexture, Pos, Src, color, 0f, Origin, Scale, SpriteEffects.None, 0f);
			else if (this.pMerged.Equals(1f))
				Sprite.Draw(DestinationTexture, Pos, Src, color, 0f, Origin, Scale, SpriteEffects.None, 0f);
			else
			{
				Sprite.Draw(OriginalTexture, Pos, Src, color, 0f, Origin, Scale, SpriteEffects.None, 0f);
				Sprite.Draw(DestinationTexture, Pos, Src, color * this.pMerged, 0f, Origin, Scale, SpriteEffects.None, 0f);
			}
		}

		/// <summary>
		/// Zeichnet zwei Texturen auf ein Sprite, wobei die Zieltextur mit dem derzeitigen Alphawert auf die andere überzeichnet wird.
		/// </summary>
		/// <param name="Sprite">Das Sprite, auf dem gezeichnet wird.</param>
		/// <param name="OriginalTexture">Die Originaltextur.</param>
		/// <param name="DestinationTexture">Die Zieltextur, die Anfangs transparant wird, mit der entsprechendem Alphawert aber undurchsichtig.</param>
		/// <param name="color">The color.</param>
		/// <param name="Dest">Ausgangsrechteck der Texturen.</param>
		/// <param name="Src">Quellrechteck.</param>
		/// <param name="Origin">Vektor, der den Nullpunkt der Textur darstellt.</param>
		public void Draw (SpriteBatch Sprite, Texture2D OriginalTexture, Texture2D DestinationTexture, Color color, Rectangle Dest, Rectangle? Src, Vector2 Origin)
		{
			if (this.pMerged.Equals(0f))
				Sprite.Draw(OriginalTexture, Dest, Src, color, 0f, Origin, SpriteEffects.None, 0f);
			else if (this.pMerged.Equals(1f))
				Sprite.Draw(DestinationTexture, Dest, Src, color, 0f, Origin, SpriteEffects.None, 0f);
			else
			{
				Sprite.Draw(OriginalTexture, Dest, Src, color, 0f, Origin, SpriteEffects.None, 0f);
				Sprite.Draw(DestinationTexture, Dest, Src, color * this.pMerged, 0f, Origin, SpriteEffects.None, 0f);
			}
		}
	}
}